/**********************************************************************************
// SoundDemo
// 
// Creation:	12 Oct 2007
// Last Update: 27 May 2011
// Compiler:	Visual Studio 2011
//
// Notes:		Test the direct sound functions
//				Play and work with wav sounds
//
**********************************************************************************/

#define WIN32_LEAN_AND_MEAN  // just say no to MFC

#include "Resources.h"
#include "Anabele.h"
#include <list>
using std::list;


/**********************************************************************************/
/*                          SoundDemo Class                                       */
/**********************************************************************************/

class SoundDemo: public D3DGame
{
private:
	Sprite * demobox;
	Sprite * demobar;
	Input input;
	Sound snd;

	int volume;
	int frequency;
	int pan;

	bool keyboardOn;
	bool mouseOn;
	bool joystickOn;

	Poly   plane;

	char text[256];

public:
	SoundDemo();
	void InitObjects();

	void GameInit();
	void GameLogic();
	void GameDraw();
	void GameShutDown();
	void UnloadResources();
	void LoadResources();
};

/**********************************************************************************/

SoundDemo::SoundDemo()
{
	keyboardOn = false;
	mouseOn    = false;
	joystickOn = false;
}

/**********************************************************************************/
void SoundDemo::InitObjects()
{
	Point vlist[24] = {Point(1,11),
                          Point(2,8),
						  Point(1,7),
						  Point(1,-1),
						  Point(3,-1),
						  Point(3,-2),
						  Point(11,-3),
						  Point(11,-6),
						  Point(3,-7),
						  Point(2,-8),
						  Point(1,-8),
						  Point(1,-7),
						  Point(-1,-7),
						  Point(-1,-8),
						  Point(-2,-8),
						  Point(-3,-7),
						  Point(-11,-6),
						  Point(-11,-3),
						  Point(-3,-2),
						  Point(-3,-1),
						  Point(-1,-1),
						  Point(-1,7),
						  Point(-2,8),
						  Point(-1, 11)};

	plane = Poly(vlist, 24);
	plane.Scale(8.0f, 8.0f);
	plane.MoveTo(GetWindowWidth()/2.0f, GetWindowHeight()/2.0f);

	volume = 10000;
	frequency = 11025;
	pan = 0;

	snd.Volume(0,10000);
	snd.Pan(0,0);
	snd.Frequency(0,11025);
}

/**********************************************************************************/

void SoundDemo::GameInit()
{
	srand(GetTickCount());

	input.Initialize();
	keyboardOn = input.InitializeKeyboard();
	mouseOn    = input.InitializeMouse();
	joystickOn = input.InitializeJoystick();

	snd.Initialize();	
	snd.Load("Resources\\starsng.wav");
	snd.Play(0,1);

	snd.Load("Resources\\engines.wav");

	InitObjects();

	LoadResources();
}

/**********************************************************************************/

void SoundDemo::LoadResources()
{
	demobox = new Sprite("Resources/demoBox.png");
	demobox->MoveTo(155, 100);

	demobar = new Sprite("Resources/demoBigBar.png");
	demobar->MoveTo(GetWindowWidth()/2.0f, GetWindowHeight()-30.0f);
}

/**********************************************************************************/

void SoundDemo::UnloadResources()
{
	if (demobox) delete demobox;
	if (demobar) delete demobar;
}

/**********************************************************************************/

void SoundDemo::GameShutDown()
{
	UnloadResources();
}


/**********************************************************************************/

void SoundDemo::GameLogic()
{

	// Quits by pressing ESC
	EndsOnEscape();

	// ==== Keyboard input ====
	if (keyboardOn)
	{
		// Update keyboard state
		input.GetKeyboardState();

		// Restart Game (R)
		if (input.KeyPressed(DIK_R))
			InitObjects();

		if (joystickOn)
		{
			// Select Next Joystick (Page Down)
			if (input.KeyPressed(DIK_NEXT))
				input.JoystickSelectNext();

			// Select Previous Joystick (Page Up)
			if (input.KeyPressed(DIK_PRIOR))
				input.JoystickSelectPrev();
		}

		// Rotate (Z and X)
		if (input.KeyPressed(DIK_Z)) // rotate left
			plane.Rotate(-5);
		if (input.KeyPressed(DIK_X)) // rotate right
			plane.Rotate(5);

		// Translate 
		// (Right, Left, Up and Down)
		if (input.KeyPressed(DIK_RIGHT)) // translate right
			plane.Translate(10,0);
		if (input.KeyPressed(DIK_LEFT))  // translate left
			plane.Translate(-10,0);    
		if (input.KeyPressed(DIK_UP))    // translate up
			plane.Translate(0,-10); 
		if (input.KeyPressed(DIK_DOWN))  // translate down
			plane.Translate(0,10);

		// Activate Sound Effects
		if (input.KeyPressed(DIK_A))
			snd.Play(1,0);
		if (input.KeyPressed(DIK_S))
			snd.Stop(1);
		if (input.KeyPressed(DIK_D))
		{	
			if (volume < 10000) 
				volume+=10;
			snd.Volume(0, volume);
		}
		if (input.KeyPressed(DIK_F))
		{	
			if (volume > 0) 
				volume-=10;
			snd.Volume(0, volume);
		}
		if (input.KeyPressed(DIK_G))
		{	
			if (pan > -10000) 
				pan -= 100;
			snd.Pan(0, pan);
		}
		if (input.KeyPressed(DIK_H))
		{	
			if (pan < 10000) 
				pan += 100;
			snd.Pan(0, pan);
		}
		if (input.KeyPressed(DIK_J))
		{	
			if (frequency < 100000) 
				frequency += 100;
			snd.Frequency(0,frequency);
		}
		if (input.KeyPressed(DIK_K))
		{	
			if (frequency > 100) 
				frequency -= 100;
			snd.Frequency(0,frequency);
		}
	}


	// ==== Joystick input ====
	if (joystickOn)
	{
		// Update joystick state
		input.GetJoystickState();
	
		// Restart Game
		if (input.JoystickButton(7))
			InitObjects();

		// Translate (left analog stick)
		plane.Translate(input.JoystickAxis(JoyAxisX)/50.0f, input.JoystickAxis(JoyAxisY)/50.0f);
		
		// Rotate (right analog stick)
		if (input.JoystickAxis(JoyAxisRX)<0)
			plane.Rotate(float(input.JoystickAxis(JoyAxisRX)/100));
		if (input.JoystickAxis(JoyAxisRX)>0)
			plane.Rotate(float(input.JoystickAxis(JoyAxisRX)/100));

		// Rotate (AxisZ)
		if (input.JoystickAxis(JoyAxisZ)<0)
			plane.Rotate(float(input.JoystickAxis(JoyAxisZ)/100));
		if (input.JoystickAxis(JoyAxisZ)>0)
			plane.Rotate(float(input.JoystickAxis(JoyAxisZ)/100));

		// Activate Sound Effects
		if (input.JoystickButton(0))
			snd.Play(1,0);
		if (input.JoystickButton(1))
			snd.Stop(1);
		if (input.JoystickButton(2))
		{	
			if (volume < 10000) 
				volume+=10;
			snd.Volume(0, volume);
		}
		if (input.JoystickButton(3))
		{	
			if (volume > 0) 
				volume-=10;
			snd.Volume(0, volume);
		}
		if (input.JoystickButton(4))
		{	
			if (pan > -10000) 
				pan -= 100;
			snd.Pan(0, pan);
		}
		if (input.JoystickButton(5))
		{	
			if (pan < 10000) 
				pan += 100;
			snd.Pan(0, pan);
		}
		switch(input.JoystickPov(0))
		{
		case 9000:
			if (frequency < 100000) 
				frequency += 100;
			snd.Frequency(0,frequency); // go right
			break;
		case 27000:
			if (frequency > 100) 
				frequency -= 100;
			snd.Frequency(0,frequency); // go left
			break;
		}
	}

} 

/**********************************************************************************/

void SoundDemo::GameDraw()
{
	// Lock Screen for pixel plotting functions
	LockScreen();

	// Draw polygons
	plane.Draw();

	UnLockScreen();

	demobox->Draw();
	demobar->Draw();

	sprintf_s(text, "Direct Sound Demo");
	sysFont->Draw(55, 40, text);

	sprintf_s(text, "WAV Playback");
	sysFont->Draw(55, 80, text);

	sprintf_s(text, "Volume up and down");
	sysFont->Draw(55, 100, text);

	sprintf_s(text, "Pan left/right effect");
	sysFont->Draw(55, 120, text);
	
	sprintf_s(text, "Frequency increase and decrease");
	sysFont->Draw(55, 140, text);


	if (joystickOn)
	{
		sprintf_s(text, "Controls:");
		sysFont->Draw(55, 240, text);

		sprintf_s(text, "Button 1: Play sound effect");
		sysFont->Draw(55, 260, text);

		sprintf_s(text, "Button 2: Stop sound effect");
		sysFont->Draw(55, 280, text);

		sprintf_s(text, "Button 3: Increase Volume");
		sysFont->Draw(55, 300, text);

		sprintf_s(text, "Button 4: Decrease Volume");
		sysFont->Draw(55, 320, text);

		sprintf_s(text, "Button 5: Pan left");
		sysFont->Draw(55, 340, text);

		sprintf_s(text, "Button 6: Pan right");
		sysFont->Draw(55, 360, text);

		sprintf_s(text, "POV right: Increase frequency");
		sysFont->Draw(55, 380, text);

		sprintf_s(text, "POV left: Decrease frequency");
		sysFont->Draw(55, 400, text);

		sprintf_s(text, "<Z> and <X> Rotate   <Arrows> Translate   <R> Restart   <PgUp> Prev Joy   <PgDown> Next Joy");
		sysFont->Draw(0, GetWindowHeight()-37.0f, text, Color(255,255,255), GetWindowWidth(), 30, DT_CENTER);
	}
	else
	{
		sprintf_s(text, "Controls:");
		sysFont->Draw(55, 240, text);

		sprintf_s(text, "A: Play sound effect");
		sysFont->Draw(55, 260, text);

		sprintf_s(text, "S: Stop sound effect");
		sysFont->Draw(55, 280, text);

		sprintf_s(text, "D: Increase Volume");
		sysFont->Draw(55, 300, text);

		sprintf_s(text, "F: Decrease Volume");
		sysFont->Draw(55, 320, text);

		sprintf_s(text, "G: Pan left");
		sysFont->Draw(55, 340, text);

		sprintf_s(text, "H: Pan right");
		sysFont->Draw(55, 360, text);

		sprintf_s(text, "J: Increase frequency");
		sysFont->Draw(55, 380, text);

		sprintf_s(text, "K: Decrease frequency");
		sysFont->Draw(55, 400, text);

		sprintf_s(text, "<Z> and <X> Rotate   <Arrows> Translate   <R> Restart");
		sysFont->Draw(0, GetWindowHeight()-37.0f, text, Color(255,255,255), GetWindowWidth(), 30, DT_CENTER);
	}
} 



/**********************************************************************************/
/*                                  WinMain                                       */
/**********************************************************************************/

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	SoundDemo demo = SoundDemo();

	demo.SetWindowBgColor(10,25,55);
	demo.SetWindowTitle(string("Direct Sound Demo"));
	demo.SetWindowIcon(LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON)));
	demo.ShowWindowCursor(false);
	demo.Initialize(hInstance);
	demo.Start();
	
	return 0;

}

/**********************************************************************************/